/* Testing for isGameOver function */

#include "dominion.h"
#include "dominion_helpers.h"
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "rngs.h"

// set TEST_OUTPUT to 0 to remove printfs from output
#define TEST_OUTPUT 0

int main() {
	int i, j, m;
	int gameover;
	int seed = 100;
	int numPlayer = 2;
	//From the example
	int k[10] = {adventurer, council_room, feast, gardens, mine, remodel, smithy, village, baron, great_hall};
	struct gameState G;
	struct gameState G_init;
	//Taken from the example testUpdateCoins.c, but still quite necessary.
	memset(&G, 23, sizeof(struct gameState));   			// clear the game state
    initializeGame(numPlayer, k, seed, &G); 			// initialize a new game
	memcpy(&G_init, &G, sizeof(struct gameState));		//Copy the initialized game state for future reference and state adjustment.
	
	//To test isGameOver, need to check if a stack of province cards are all gone, or not, then check if three supply piles are empty
	if (TEST_OUTPUT)
	{
	printf("Begin by testing if the stack of province cards is empty.\n");
	printf("This will be done by keeping all the cards at initial levels, then manipulating all cards piles first to 1, then 0.\nThis will occur one stack at a time, then two, then three, and so on up to all stacks at zero and check against expected results.\nCards initialized at -1, will not be touched.\n\n");
	}
	gameover = isGameOver(&G);
	if (TEST_OUTPUT) printf("gameover expected 0, returned %d\n", gameover);
	assert(gameover == 0);
	
	G.supplyCount[province] = 1;
	gameover = isGameOver(&G);
	if (TEST_OUTPUT) printf("gameover expected 0, returned %d\n", gameover);
	assert(gameover == 0);
	
	G.supplyCount[province] = 0;
	gameover = isGameOver(&G);
	if (TEST_OUTPUT) printf("gameover expected 1, returned %d\n", gameover);
	assert(gameover == 1);
	
	memcpy(&G, &G_init, sizeof(struct gameState));		//Reset the game state to init
	gameover = 0;
	
	//cycle through all the possible card piles, if the pile level -1, break and go to the next card, if the card is province, break and skip that one too.
	//One card changed at a time first.
	for (i = 0; i < (treasure_map + 1); ++i)
	{
		if (i == province || G.supplyCount[i] == -1)
		{
			//Do nothing and go back around
		} else {
			//Perform checks
			G.supplyCount[i] = 1;
			gameover = isGameOver(&G);
			if (TEST_OUTPUT) printf("i = %d; gameover expected 0, returned %d\n", i, gameover);
			assert(gameover == 0);
			
			G.supplyCount[i] = 0;
			gameover = isGameOver(&G);
			if (TEST_OUTPUT) printf("i = %d; gameover expected 0, returned %d\n", i, gameover);
			assert(gameover == 0);
		}
		memcpy(&G, &G_init, sizeof(struct gameState));		//Reset the game state to init
		gameover = 0;
	}
	
	//Two cards at a time.
	for (i = 0; i < (treasure_map + 1); ++i)
	{
		if (i == province || G.supplyCount[i] == -1 )
		{
			//Do nothing and go back around
		} else {
			for (j = 0; j < (treasure_map +1); ++j)
			{
				if (i == j || j == province  || G.supplyCount[j] == -1 )
				{
					//Do nothing and go back around
				} else {
					//Perform checks					
					G.supplyCount[i] = 1;
					G.supplyCount[j] = 1;
					gameover = isGameOver(&G);
					if (TEST_OUTPUT) printf("i = %d, j = %d; gameover expected 0, returned %d\n", i, j, gameover);
					assert(gameover == 0);
					
					G.supplyCount[i] = 0;
					G.supplyCount[j] = 0;
					gameover = isGameOver(&G);
					if (TEST_OUTPUT) printf("i = %d, j = %d; gameover expected 0, returned %d\n", i, j, gameover);
					assert(gameover == 0);
				}
				memcpy(&G, &G_init, sizeof(struct gameState));		//Reset the game state to init
				gameover = 0;
			}
		}
	}
	
	//now for three
	for (i = 0; i < (treasure_map + 1); ++i)
	{
		if (i == province || G.supplyCount[i] == -1 )
		{
			//Do nothing and go back around
		} else {
			for (j = 0; j < (treasure_map +1); ++j)
			{
				if (i == j || j == province  || G.supplyCount[j] == -1 )
				{
					//Do nothing and go back around
				} else {
					for (m = 0; m < (treasure_map +1); ++m)
					{
						if (i == m || j == m || m == province  || G.supplyCount[m] == -1 )
						{
							//Do nothing and go back around
						} else {
							//Perform checks					
							G.supplyCount[i] = 1;
							G.supplyCount[j] = 1;
							G.supplyCount[m] = 1;
							gameover = isGameOver(&G);
							if (TEST_OUTPUT) printf("i = %d, j = %d, m = %d; gameover expected 0, returned %d\n", i, j, m, gameover);
							assert(gameover == 0);
							
							G.supplyCount[i] = 0;
							G.supplyCount[j] = 0;
							G.supplyCount[m] = 0;
							gameover = isGameOver(&G);
							if (TEST_OUTPUT) printf("i = %d, j = %d, m = %d; gameover expected 1, returned %d\n", i, j, m, gameover);
							assert(gameover == 1);
						}
						memcpy(&G, &G_init, sizeof(struct gameState));		//Reset the game state to init
						gameover = 0;
					}
				}
			}
		}
	}
	
	printf("Unittest1: All Tests Passed!\n");
	return 0;
}
